/*----------------------------------------------------------------------------
 * Copyright (c) <2016-2018>, <Huawei Technologies Co., Ltd>
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific prior written
 * permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
 * Notice of Export Control Law
 * ===============================================
 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
 * applicable export control laws and regulations.
 *---------------------------------------------------------------------------*/
#include "main.h"
#include "sys_init.h"
#ifndef WITH_AT_FRAMEWORK
#include "agent_tiny_demo.h"
#else
#include "los_base.h"
#include "los_task.ph"
#include "los_typedef.h"
#include "los_sys.h"
#endif
#if defined WITH_AT_FRAMEWORK
#include "at_api_interface.h"
#if defined USE_NB_NEUL95
#include "los_nb_api.h"
#endif
#endif
#ifdef SUPPORT_DTLS_SRV
#include "test_dtls_server.h"
#endif

#include "w25qxx.h"
#include "bsp.h"
#include "sdram.h"
#include "mcu_omip.h"
#include "ad7708.h"
#include "sdp800.h"
#include "pca9538.h"
#include "pca9555.h"
#include "modbus.h"
#include "bsp_api.h"
#include "hal_iwdg.h"
#include "bc95.h"
#include "hardware_com.h"
#include "app_common.h"
#include "omip_log.h"

static UINT32 TskHandle_tast =0;	//任务句柄ID
char *g_mcu_version = "2.0.52-21.1.T4.B010";
int32_t nb_cmd_match(const char *buf, char* featurestr,int len)
{
    printf("buf:%s feature:%s\n",buf,featurestr);
    return strncmp((const char *)(buf+2),featurestr,len);
}

#ifndef BOOTLOADER_FLAG
static int jump_addr(void *addr)
{
    unsigned int start_cmd;
    int (*jump_func)(void );
    start_cmd = *(unsigned int *)(addr);
    jump_func = (int (*)(void))(start_cmd);
    printf("jump addr:0x%02x, func:0x%02x\r\n",(unsigned int)(addr),(unsigned int)jump_func);
    jump_func();
    return 0;  //maybe never come back
}
#endif

VOID HardWare_Init(VOID) //硬件初始化
{
    SystemClock_Config();
	USR_GPIO_Config();  // ad
    MX_UART5_Init();
    hal_rng_config();
    dwt_delay_init(SystemCoreClock);
    USR_SPI_Init(); // w25+ad
    W25QXX_Init();
	LED_SYS_NORMAL_(LED_OPEN);	
	LED_SYS_FAULT_(LED_OPEN);
#ifdef BOOTLOADER_FLAG
	SDRAM_Init();     // sdram
	LED_RS485_1_(LED_CLOSE);
	LED_RS485_2_(LED_CLOSE);
	ETH1_(LED_CLOSE);
	PLC_WIFI_ETH2_(LED_CLOSE);
	USR_IIC_Init();   // i2c+pca+sdp
    USR_PWM_Config(10000-1, 90-1);// pwm_100Hz
    MOTOR_CTL(0,100);  // 电机停转
    hal_iwdg_config(IWDG_PRESCALER_256, 3730);  // iwdg
#endif
}

VOID main_task(VOID)
{
#if defined(WITH_LINUX) || defined(WITH_LWIP)
    hieth_hw_init();
    //net_init();
#elif defined(WITH_AT_FRAMEWORK) && defined(USE_NB_NEUL95)
#define AT_DTLS 0
#if AT_DTLS
    sec_param_s sec;
    sec.setpsk = 1;
    sec.pskid = "868744031131026";
    sec.psk = "d1e1be0c05ac5b8c78ce196412f0cdb0";
#endif
    printf("\r\n=====================================================");
    printf("\r\nSTEP1: Init NB Module( NB Init )");
    printf("\r\n=====================================================\r\n");
#if AT_DTLS
    los_nb_init((const int8_t *)"180.101.147.115", (const int8_t *)"5684", &sec);
#else
    los_nb_init((const int8_t *)"180.101.147.115", (const int8_t *)"5683", NULL); //"139.159.140.34"
#endif
    printf("\r\n=====================================================");
    printf("\r\nSTEP2: Register Command( NB Notify )");
    printf("\r\n=====================================================\r\n");
    // los_nb_notify("+NNMI:",strlen("+NNMI:"),nb_data_rcv_handler,nb_cmd_match);
    // osDelay(3000);
    printf("\r\n=====================================================");
    printf("\r\nSTEP3: Report Data to Server( NB Report )");
    printf("\r\n=====================================================\r\n");
    los_nb_report("22", 2);
    los_nb_report("23", 1);
    // los_nb_deinit();
#elif defined(WITH_AT_FRAMEWORK) && (defined(USE_ESP8266) || defined(USE_SIM900A) || defined(USE_NB_NEUL95))
    extern at_adaptor_api at_interface;
    printf("\r\n=============agent_tiny_entry============================\n");
    los_nb_init(NULL,NULL,NULL);
    los_nb_notify("+NSONMI:",strlen("+NSONMI:"),nb_data_rcv_handler,nb_cmd_match);
    at_api_register(&at_interface);
    agent_tiny_entry();
#endif
#if defined(WITH_LINUX) || defined(WITH_LWIP)
    agent_tiny_entry();
#endif
}

UINT32 creat_main_task()
{
	static UINT32 	g_TskHandle;
    UINT32 uwRet = LOS_OK;
    TSK_INIT_PARAM_S task_init_param;
    task_init_param.usTaskPrio = 25;
    task_init_param.pcName = "main_task";
    task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)main_task;
#ifdef CONFIG_FEATURE_FOTA
    task_init_param.uwStackSize = 0x2000; /* fota use mbedtls bignum to verify signature  consuming more stack  */
#else
    task_init_param.uwStackSize = 0x1000;
#endif
    uwRet = LOS_TaskCreate(&g_TskHandle, &task_init_param);
    if(LOS_OK != uwRet)	return uwRet;
    return uwRet;
}

void task_tast_001()
{
    mcu_demo_main(); 						//MCU主任务
    ad7708_Init(); //AD初始化必须放在线程里 所以放这
    OMIP_LOG_INFO("ad7708 init success.\r\n");
    get_paneldata(); 						//获取面板数据任务
    get_pressure_and_valvedegree_thread();	//读风阀开度任务
    LOS_TaskDelete(TskHandle_tast);  		//释放任务
}

UINT32 creat_task_init_test()
{
	TSK_INIT_PARAM_S task_init_pid_operation_branch;                 			//任务初始化所需的参数-结构体，可临时变量
	//LOS_TaskLock();                                                			//锁任务调度,防止一创建就跑那个任务去了,如果不在任务/进程里就不用锁
	task_init_pid_operation_branch.usTaskPrio = 2;                           	//任务优先级，越小越优先  0-31
	task_init_pid_operation_branch.pcName ="test_task";                    		//任务名，暂时没用，但别重复
	task_init_pid_operation_branch.pfnTaskEntry =(TSK_ENTRY_FUNC)task_tast_001;	//任务函数名
	//task_init_pid_operation_branch.uwStackSize =0x2400;
	task_init_pid_operation_branch.uwStackSize =1024;
	UINT32 uwRet =LOS_TaskCreate(&TskHandle_tast, &task_init_pid_operation_branch); //创建任务
	if(uwRet !=LOS_OK) printf("[%s:%d]LOS_TaskCreate failed,ret=0x%x.\r\n",__FUNCTION__,__LINE__,uwRet);
	//LOS_TaskUnlock();  //解锁任务调度
	return uwRet;
}

int main(void)
{
    UINT32 uwRet = LOS_OK;
    HardWare_Init(); //硬件初始化
	print_debug(0, "VERSION:%s\r\n", g_mcu_version);

#ifdef BOOTLOADER_FLAG
    printf("this is app...\r\n");

    uwRet = LOS_KernelInit(); //LiteOS内核启动
    if (uwRet !=LOS_OK)	return LOS_NOK;
	
	USART1_UART_Init();
	USART3_UART_Init();
	print_debug(0, "VERSION:%s\r\n", g_mcu_version);
	print_debug(0, "LOS Kernel init OK!\r\n");

    //USART1_UART_Init(); //须在LiteOS初始化之后
    uwRet = creat_main_task(); //系统主任务
    if (uwRet != LOS_OK) return LOS_NOK;
    creat_task_init_test(); //用户任务
#else
    print_debug(0,"this is bootloader...\r\n");
    upgrade();
    jump_addr((void *)cn_app_bin_addr);
    return 0;
#endif
    (void)LOS_Start();
    printf("[%s:%d]should not come here!\r\n",__FUNCTION__,__LINE__);
    return 0;
}

